package org.example.io.ex6;

import java.io.*;
import java.util.regex.Pattern;
import java.util.zip.*;

public class TTT {
    public static void main(String[] args) {
        try {
//            zip();
            unzip();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static void zip() throws IOException {
        File fileSrc = new File("D:\\asd"); // 目标文件或文件夹
        File destFile = new File("D:\\asd.zip"); // 压缩文件路径
        zip(fileSrc, destFile);
    }

    public static void zip(File fileSrc, File fileDect) throws IOException {
        // 将ZipOutputStream与压缩包目标路径绑定
        ZipOutputStream zipOutputStream = new ZipOutputStream(new FileOutputStream(fileDect));
        // 获取目标文件或文件夹名称
        String name = fileSrc.getName();
        // 开始压缩
        zip(zipOutputStream, name, fileSrc);
        zipOutputStream.flush();
        zipOutputStream.close();
    }

    private static void zip(ZipOutputStream zipOutputStream, String name, File fileSrc) throws IOException {
        if (fileSrc.isDirectory()) {
            // 若当前file为文件夹
            // 建一个文件夹
            zipOutputStream.putNextEntry(new ZipEntry(name + "/"));
            zipOutputStream.closeEntry();
            // 筛选当前文件夹下的文件&文件夹
            File[] files = fileSrc.listFiles(
                    new FilenameFilter() { //过滤文件
                        // 正则表达式：这里选择过滤所有文件(没有过滤),有需要可以更改正则表达式
                        final Pattern pattern = Pattern.compile(".+");
                        @Override
                        public boolean accept(File dir, String name) {
                            return pattern.matcher(name).matches();
                        }
                    }
            );
            // 深度遍历，压缩当前目录下的其他文件
            for (File f : files != null ? files : new File[0]) {
                zip(zipOutputStream, name + "/" + f.getName(), f); // 不要忘了增长文件路径
            }
        } else {
            // 若当前file为文件
            zipOutputStream.putNextEntry(new ZipEntry(name));
            FileInputStream input = new FileInputStream(fileSrc);
            byte[] buf = new byte[1024];
            int len;
            while ((len = input.read(buf)) != -1) {
                zipOutputStream.write(buf, 0, len);
            }
            input.close();
            zipOutputStream.closeEntry();
        }
    }

    public static void unzip() throws IOException {
        File zipFile = new File("D:\\asd.zip");
        String destDir = "D:\\";
        unzip(zipFile, destDir);
    }

    private static void unzip(File zipFile, String destDir) throws IOException {
        ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(zipFile));
        ZipEntry zipEntry;
        while ((zipEntry = zipInputStream.getNextEntry()) != null) {
            System.out.println(destDir + " " + zipEntry.getName());
            File f = new File(destDir, zipEntry.getName());
            if (zipEntry.getName().endsWith("/")) {
                f.mkdirs();
            } else {
                FileOutputStream fileOutputStream = new FileOutputStream(f);
                byte[] buf = new byte[1024];
                int len;
                while ((len = zipInputStream.read(buf)) != -1) {  // 直到读到该条目的结尾
                    fileOutputStream.write(buf, 0, len);
                }
                fileOutputStream.flush();
                fileOutputStream.close();
            }
            zipInputStream.closeEntry();  //关闭该条目
        }
        zipInputStream.close();
    }
}
